package com.lemon.bean.stageBean;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import static com.lemon.beanManager.BeanContainer.beanFactory;

public class LoadPlay {
    private Pane playWindow;
    private Stage stage = new Stage();
    public Button min;
    public Button max;
    public Button shut;
    private Button delete;
    private Button enlarge;
    private Button frontPic;
    private Button nextPic;
    private Button play;
    private Button rotate;
    private Button shrink;
    private HBox playBox;
    private AnchorPane playPane;

    //数据
    private List<String> imageFileNameList = new ArrayList<>();


    private Integer curIndex=0;
    private Tooltip tooltip = new Tooltip();

    //延时器 用于延迟关闭那个提示
    private Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2),e->{
        tooltip.hide();
        shutTimeLine();
    }));

    private void shutTimeLine() {
        if (timeline!=null) {
            timeline.stop();
        }
    }

    //加载
    public void loadPlay(){
        try {
            playWindow = FXMLLoader.load(this.getClass().getResource("Play.fxml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scene scene = new Scene(playWindow,1200,700);
        stage.setScene(scene);
        min = (Button) beanFactory.getBean("secondMin");
        max = (Button) beanFactory.getBean("secondMax");
        shut = (Button) beanFactory.getBean("secondClose");
        nextPic = (Button) beanFactory.getBean("secondNextPic");
        frontPic = (Button) beanFactory.getBean("secondFrontPic");
        playBox = (HBox) beanFactory.getBean("secondPlayBox");
        play = (Button) beanFactory.getBean("secondPlay");

        enlarge = (Button) beanFactory.getBean("secondEnlarge");
        shrink = (Button) beanFactory.getBean("secondShrink");
        //
        tooltip.setFont(new Font(20));
        tooltip.setTextAlignment(TextAlignment.JUSTIFY);
        tooltip.setPrefWidth(300);
        tooltip.setPrefHeight(100);
        tooltip.show(stage);

    }
    private void onClickFrontPic() {

        List<String> stringList = imageFileNameList;
        nextPic.setDisable(false);
        nextPic.setOpacity(1);
        curIndex=(curIndex-1)%stringList.size();
        Image image = new Image(stringList.get(curIndex),2000,2000,true,true,true);
        if(curIndex<=0){
            tooltip.setText("             已经是第一张了！");
            tooltip.show(stage);
            timeline.play();
            frontPic.setDisable(true);
            frontPic.setOpacity(0);
        }
        ImageView imageView = (ImageView) playBox.getChildren().get(0);
        imageView.setImage(image);
        resetImageTransform(imageView);
    }
    private void onClickNextPic() {

        List<String> stringList = imageFileNameList;
        frontPic.setDisable(false);
        frontPic.setOpacity(1);
        curIndex=(curIndex+1)%stringList.size();
        Image image = new Image(stringList.get(curIndex),2000,2000,true,true,true);

        if(curIndex>=stringList.size()-1){
            tooltip.setText("             最后一张啦！");
            tooltip.show(stage);
            timeline.play();
            nextPic.setDisable(true);
            nextPic.setOpacity(0);
        }
        ImageView imageView = (ImageView) playBox.getChildren().get(0);
        imageView.setImage(image);
        resetImageTransform(imageView);

    }

    public void initFunction(){
        min.setOnMouseClicked(e->{stage.setIconified(true);});
        max.setOnMouseClicked(e->{
            if(stage.isMaximized()){
                stage.setMaximized(false);
            }else{
                stage.setMaximized(true);
            }
        });
        shut.setOnMouseClicked(e->{
            close();});
        frontPic.setOnMouseClicked(event -> {
            onClickFrontPic();
        });
        nextPic.setOnMouseClicked(event -> {
            onClickNextPic();
        });
        play.setOnMouseClicked(event -> {
            playOnClick();
        });
        shrink.setOnMouseClicked(event -> {
            shrinkOnClick(event);
        });

        enlarge.setOnMouseClicked(event -> {
            enlargeOnClick(event);
        });
        stage.setOnCloseRequest(e->{
            close();
        });
        URL resource = this.getClass().getResource("css/play.css");
        addStyle(resource.toExternalForm());
    }

    public void initBigSmallPref(){
        playBox.widthProperty().addListener((observableValue, number, t1) -> {
            Rectangle rec = new Rectangle((Double) t1,playBox.getHeight());
            playBox.setClip(rec);
            //清除缩放
            ImageView imageView = (ImageView) playBox.getChildren().get(0);
            resetImageTransform(imageView);
        });
        playBox.heightProperty().addListener((observableValue, number, t1) -> {
            Rectangle rec = new Rectangle(playBox.getWidth(), (Double) t1);
            playBox.setClip(rec);
            //清除缩放
            ImageView imageView = (ImageView) playBox.getChildren().get(0);
            resetImageTransform(imageView);
        });
        //缩放记录列表
        List<Double> rateListX = new LinkedList<>();
        List<Double> rateListY = new LinkedList<>();
        ImageView imageView = (ImageView) playBox.getChildren().get(0);
        //滚轮缩放
        playBox.addEventHandler(ScrollEvent.SCROLL, scrollEvent -> {
            double rate = (double) beanFactory.getBean("rate");
            double rateOffset = 0.1;
            //限制最小缩放
            if (scrollEvent.getDeltaY() < 0){
                if (Math.abs(imageView.getTranslateX()) > 0.001 || (Math.abs(imageView.getTranslateY()) > 0.001)){
                    imageView.setTranslateX(imageView.getTranslateX() * 0.5);
                    imageView.setTranslateY(imageView.getTranslateY() * 0.5);
                }else{
                    imageView.setTranslateX(0);
                    imageView.setTranslateY(0);
                }
                if (rate < 0.5){
                    return;
                }
                rateOffset = -rateOffset;
            }
            rate += rateOffset;
            beanFactory.setBean("rate",rate);
            imageView.fitWidthProperty().bind(playBox.widthProperty().multiply(rate));
            imageView.fitHeightProperty().bind(playBox.heightProperty().multiply(rate));
        });
        imageView.addEventFilter(ScrollEvent.SCROLL,scrollEvent -> {
            scrollEvent.consume();
            double rate = (double) beanFactory.getBean("rate");
            double rateOffset = 0.1;
            if (scrollEvent.getDeltaY() < 0){
                if (rate < 0.5){
                    return;
                }
                rateOffset = -rateOffset;
            }
            rate += rateOffset;
            beanFactory.setBean("rate",rate);
            /*
            偏移说明：
            1.对于一次缩放倍率为rate的缩放，其(0,0)点的偏移应为(rate(n) / rate(n - 1) - 1) * (x,y) / 2，其中(x,y)是变化前图片的大小
            2.因此对于放大点(a,b)，其偏移应为(0,0)点的偏移 - (rate - 1) * (a,b)，其中a,b相对于图片
             */
            double imgHeight = imageView.prefHeight(-1);
            double imgWidth = imageView.prefWidth(-1);
            //定点缩放
            //不超过显示框大小无需偏移
            if (imgHeight * rate > playBox.getHeight() || imgWidth * rate > playBox.getWidth()){
                Point2D imagePoint;
                //(0,0)点偏移
                double translateX;
                double translateY;
                //初始偏移为(0,0)
                if (rateListX.size() == 0){
                    translateX = 0;
                    translateY = 0;
                }else {
                    translateX = imageView.getTranslateX();
                    translateY = imageView.getTranslateY();
                }
                double ratio = (rate / (rate - rateOffset) - 1);
                //叠加上次(0,0)偏移
                translateX += ratio * (imgWidth) / 2;
                translateY += ratio * (imgHeight) / 2;
                //(a,b)点偏移
                Point2D eventPoint = new Point2D(scrollEvent.getSceneX(), scrollEvent.getSceneY());
                imagePoint = imageView.sceneToLocal(eventPoint);
                //叠加上次(a,b)偏移
                translateX -= ratio * imagePoint.getX();
                translateY -= ratio * imagePoint.getY();
                rateListX.add(translateX);
                rateListY.add(translateY);
                imageView.setTranslateX(translateX);
                imageView.setTranslateY(translateY);
            }else{
                imageView.setTranslateX(0);
                imageView.setTranslateY(0);
                rateListX.clear();
                rateListY.clear();
            }
            //缩放
            imageView.fitWidthProperty().bind(playBox.widthProperty().multiply(rate));
            imageView.fitHeightProperty().bind(playBox.heightProperty().multiply(rate));
        });
        imageView.addEventFilter(MouseEvent.MOUSE_PRESSED,mouseEvent -> {
            double startX = mouseEvent.getX();
            double startY = mouseEvent.getY();
            Point2D startPoint = new Point2D(startX,startY);
            System.out.println(startPoint);
            beanFactory.setBean("dragStartPoint",startPoint);
        });
        imageView.setOnDragDetected(mouseDragEvent -> {
            imageView.startFullDrag();
        });
        imageView.setOnMouseDragOver(mouseDragEvent -> {
            Point2D startPoint = (Point2D) beanFactory.getBean("dragStartPoint");
            double startX = startPoint.getX();
            double startY = startPoint.getY();
            double endX = mouseDragEvent.getX();
            double endY = mouseDragEvent.getY();
            double offsetX = imageView.getTranslateX() + endX - startX;
            double offsetY = imageView.getTranslateY() + endY - startY;
            for (int i = 0; i < rateListX.size(); i++) {
                //叠加偏移
                rateListX.set(i, rateListX.get(i) + endX - startX);
                rateListY.set(i, rateListY.get(i) + endY - startY);
            }
            imageView.setTranslateX(offsetX);
            imageView.setTranslateY(offsetY);
        });
        beanFactory.setBean("rate",1.0);
    }
    private void enlargeOnClick(MouseEvent event) {
        double rateOffset = 0.1;
        double rate = (double) beanFactory.getBean("rate");
        ImageView imageView = (ImageView) playBox.getChildren().get(0);
        rate += rateOffset;
        beanFactory.setBean("rate",rate);
        imageView.fitWidthProperty().bind(playBox.widthProperty().multiply(rate));
        imageView.fitHeightProperty().bind(playBox.heightProperty().multiply(rate));
    }
    private void shrinkOnClick(MouseEvent event) {
        double rateOffset = 0.1;
        double rate = (double) beanFactory.getBean("rate");
        ImageView imageView = (ImageView) playBox.getChildren().get(0);
        rate -= rateOffset;
        if (Math.abs(imageView.getTranslateX()) > 0.001 || (Math.abs(imageView.getTranslateY()) > 0.001)){
            imageView.setTranslateX(imageView.getTranslateX() * 0.5);
            imageView.setTranslateY(imageView.getTranslateY() * 0.5);
        }else{
            imageView.setTranslateX(0);
            imageView.setTranslateY(0);
        }
        if (rate < 0.5){
            return;
        }
        beanFactory.setBean("rate",rate);
        //缩小
        imageView.fitWidthProperty().bind(playBox.widthProperty().multiply(rate));
        imageView.fitHeightProperty().bind(playBox.heightProperty().multiply(rate));
    }
    private void resetImageTransform(ImageView imageView){
        imageView.setTranslateX(0);
        imageView.setTranslateY(0);
        imageView.fitWidthProperty().bind(playBox.widthProperty());
        imageView.fitHeightProperty().bind(playBox.heightProperty());
        beanFactory.setBean("rate",1.0);
    }

    //初始化图片前置处理器
    public void initImagePre(String curImage){
        Image image = new Image(curImage,2000,2000,true,true,true);
        List<String> stringList = imageFileNameList;

        int size = stringList.size();
        for(int i=0;i<size;i++){
            if (stringList.get(i).equals(curImage)) {
                curIndex=i;
                break;
            }
        }
        if(curIndex==0){
            frontPic.setDisable(true);
            frontPic.setOpacity(0);
        }
        if(curIndex==size - 1){
            nextPic.setDisable(true);
            nextPic.setOpacity(0);
        }
        ImageView imageView = new ImageView(image);

        imageView.fitWidthProperty().bind(playBox.widthProperty());
        imageView.fitHeightProperty().bind(playBox.heightProperty());

        imageView.setPreserveRatio(true);
        imageView.setSmooth(true);
        playBox.getChildren().add(imageView);
    }
    public void playOnClick() {
        LoadPlayLight pl = new LoadPlayLight();
        if (imageFileNameList!=null) {
            pl.setStringList(imageFileNameList);//设置幻灯片播放列表
            pl.setCurIndex(curIndex);//设置当前索引
            pl.loadPlayLight();//加载幻灯片播放器
            pl.show();//显示
            pl.fullScene(true);//全屏
            pl.play();
        }
    }
    public void show(){
        stage.show();
    }
    public void close(){
        System.out.println("close()...");
        beanFactory.remove("secondMin");
        beanFactory.remove("secondMax");
        beanFactory.remove("secondClose");
        beanFactory.remove("secondNextPic");
        beanFactory.remove("secondFrontPic");
        beanFactory.remove("secondPlayBox");
        beanFactory.remove("secondEnlarge");
        beanFactory.remove("secondShrink");
        imageFileNameList.clear();
        beanFactory.remove("rate");
        beanFactory.remove("dragStartPoint");

        stage.close();
    }
    public void setImageFileNameList(List<String> imageFileNameList) {
        this.imageFileNameList = imageFileNameList;
    }
    public void addStyle(String cssPath){
        playWindow.getStylesheets().add(cssPath);
    }
}
